package modelo.escenario;


import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections15.Transformer;

import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;

public class GuiaT {
	
	/*La guia T esta compuesta por un grafo
	 * donde los nodos son del tipo "Cruce"
	 * y ls aristas del tipo "Cuadra"*/
	
	private Graph<Cruce, Cuadra> grafoGuiaT;
	
	Transformer<Cuadra, Double> transformer = new Transformer<Cuadra,Double>() {
		public Double transform(Cuadra cuadra) {
		return cuadra.getPeso();
		}
	};
	
	/**Constructor de guia t recibe una lista de cuadras*/
	public GuiaT(List<Cuadra> listaCuadras){
		grafoGuiaT = new DirectedSparseMultigraph<Cruce, Cuadra>();
		Iterator<Cuadra> it = listaCuadras.iterator();
		while (it.hasNext()) {
			Cuadra cuadra = (Cuadra) it.next();
			grafoGuiaT.addEdge(cuadra, cuadra.getCruceOrigen(),cuadra.getCruceDestino());
		}
	}
	
	/**Devuelve el camino minimo (lista de cuadras) entre dos cruces*/
	@SuppressWarnings("unchecked")
	public List<Cuadra> caminoMinimo(Cruce cruceOrigen, Cruce cruceDestino){
		DijkstraShortestPath<Cruce,Cuadra> alg = new DijkstraShortestPath(grafoGuiaT,transformer);
		List<Cuadra> l = alg.getPath(cruceOrigen, cruceDestino);
		return l;
	}
	
	/**Devuelve una coleccion con todas las cuadras de la guia*/
	public Collection<Cuadra> obtenerCuadras(){
		return grafoGuiaT.getEdges();
	}
	
	/**Devuelve una coleccion con todos los cruces de la guia*/
	public  Collection<Cruce> obtenerCruces(){
		return grafoGuiaT.getVertices();
	}
	
	/**Devuelve true si la cuadra existe en la Guia T*/
	public boolean existeCuadra(Cuadra cuadra){
		return grafoGuiaT.containsEdge(cuadra);
	}
	
	/**Devuelve true si el cruce existe en la Guia T*/
	public boolean existeCruce(Cruce cruce){
		return grafoGuiaT.containsVertex(cruce);
	}
	
	/**Devuelve la cantidad de cruces de la guia T*/
	public int obtenerCantidadCruces(){
		return grafoGuiaT.getVertexCount();
	}
	
	/**Devuelve la cantidad de cuadras de la guia T*/
	public int obtenerCantidadCuadras(){
		return grafoGuiaT.getEdgeCount();
	}

	/**Obtiene las cuadras que inciden en un cruce*/
	public Collection<Cuadra> obtenerCuadrasDelCruce(Cruce cruce){
		return grafoGuiaT.getIncidentEdges(cruce);
	}
}
